package com.sh.data.engine.web.webapi.controller.integration;

import com.sh.data.engine.application.model.dto.base.PagerResponse;
import com.sh.data.engine.application.model.dto.integration.*;
import com.sh.data.engine.application.model.request.integration.*;
import com.sh.data.engine.application.service.integration.ApiWsApplicationService;
import com.sh.data.engine.common.enumDefinition.ProjectStatisticTypeEnum;
import com.sh.data.engine.common.util.ServletUtils;
import com.sh.data.engine.domain.annotation.LogExecution;
import com.sh.data.engine.domain.annotation.ProjectStatisticExecution;
import com.sh.data.engine.domain.annotation.userlog.Business;
import com.sh.data.engine.domain.annotation.userlog.EngineOperation;
import com.sh.data.engine.web.webapi.controller.base.response.RestResponseEntity;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.media.Schema;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.validation.Valid;

/**
 * @author : changkong
 * @date : 2022/3/9
 */
@Validated
@Tag(name = "接口采集 webservice", description = "接口采集 webservice API")
@RestController
@RequestMapping("/integration/api/ws")
public class ApiWsController {

    @Autowired
    private ApiWsApplicationService apiWsApplicationService;

    //    @AuthorityAnnotation(menuId = MenuEnumNew.WEB, readWriteStatus = 0, isAdd = 1)
    @GetMapping("/getOverview")
    @Operation(summary = "页面上方的概览 待发布,成功,失败")
    public RestResponseEntity<TaskOverviewDTO> getOverview() {
        Long projectId = ServletUtils.getProjectId();
        var result = apiWsApplicationService.getOverview(projectId);
        return RestResponseEntity.success(result);
    }

    //    @AuthorityAnnotation(menuId = MenuEnumNew.WEB, readWriteStatus = 0, isAdd = 1)
    @GetMapping("/getTaskList")
    @Operation(summary = "任务列表分页")
    public RestResponseEntity<PagerResponse<TaskItemDTO>> getTaskList(
        @Parameter(description = "当前页", schema = @Schema(defaultValue = "1"))
        @RequestParam(required = false, defaultValue = "1")
        Integer pageNum,
        @Parameter(description = "每页大小", schema = @Schema(defaultValue = "10"))
        @RequestParam(required = false, defaultValue = "10")
        Integer pageSize,
        @Parameter(description = "任务状态", example = "默认为-1,全部") @RequestParam(required = false)
        Integer taskStatus,
        @Parameter(description = "搜索条件", example = "") @RequestParam(required = false) String search) {
        var result = apiWsApplicationService.getTaskPage(pageNum, pageSize, taskStatus, search);
        return RestResponseEntity.success(result);
    }

    //    @AuthorityAnnotation(menuId = MenuEnumNew.WEB, readWriteStatus = 0, isAdd = 1)
    @GetMapping("/getTaskById")
    @Operation(summary = "查看任务")
    public RestResponseEntity<WsTaskDTO> getTaskById(
        @Parameter(description = "任务id") @RequestParam(required = true) Long id) {
        var result = apiWsApplicationService.getTaskById(id);
        return RestResponseEntity.success(result);
    }

    //    @AuthorityAnnotation(menuId = MenuEnumNew.WEB, readWriteStatus = 1, isAdd = 1)
    @PostMapping("/saveTask")
//    @Log(
//        business = Business.接口采集,
//        operation = Operation.ADD_UPDATE)
//    @Operation(summary = "新建/保存编辑任务")
    @LogExecution(operation = EngineOperation.ADD_UPDATE, business = Business.接口采集)
    public RestResponseEntity saveTask(@Validated @RequestBody SaveWsTaskRequest saveTaskRequest) {
        var result = apiWsApplicationService.saveTask(saveTaskRequest);
        return RestResponseEntity.success(result);
    }

    //    @AuthorityAnnotation(menuId = MenuEnumNew.WEB, readWriteStatus = 0, isAdd = 1)
    @GetMapping("/reRunTask")
//    @Log(
//        business = Business.接口采集,
//        operation = Operation.START_TASK)
    @Operation(summary = "重跑任务")
    @LogExecution(operation = EngineOperation.START_TASK, business = Business.接口采集)
    public RestResponseEntity<Long> reRunTask(
        @Parameter(description = "任务id") @RequestParam(required = true) Long taskId) {
        var result = apiWsApplicationService.reRunTask(taskId);
        return RestResponseEntity.success(result);
    }

    //    @AuthorityAnnotation(menuId = MenuEnumNew.WEB, readWriteStatus = 0, isAdd = 1)
    @GetMapping("/downlineTask")
    @Operation(summary = "下线任务")
//    @Log(
//        business = Business.接口采集,
//        operation = Operation.DEPUBLISH)
    @LogExecution(operation = EngineOperation.DEPUBLISH, business = Business.接口采集)
    public RestResponseEntity<Boolean> downlineTask(
        @Parameter(description = "任务id") @RequestParam(required = true) Long taskId) {
        var result = apiWsApplicationService.offlineTask(taskId);
        return RestResponseEntity.success();
    }

    //    @AuthorityAnnotation(menuId = MenuEnumNew.WEB, readWriteStatus = 0, isAdd = 1)
    @GetMapping("/publishTask")
    @Operation(summary = "发布任务")
//    @Log(
//        business = Business.接口采集,
//        operation = Operation.PUBLISH)
    @LogExecution(operation = EngineOperation.PUBLISH, business = Business.接口采集)
    public RestResponseEntity<Boolean> publishTask(
        @Parameter(description = "任务id") @RequestParam(required = true) Long taskId) {
        var result = apiWsApplicationService.publishTask(taskId);
        return RestResponseEntity.success(result);
    }

    //    @AuthorityAnnotation(menuId = MenuEnumNew.WEB, readWriteStatus = 0, isAdd = 1)
    @GetMapping("/delete")
//    @Log(
//        business = Business.接口采集,
//        operation = Operation.DEL)
    @Operation(summary = "删除任务")
    @LogExecution(operation = EngineOperation.DEL, business = Business.接口采集)
    public RestResponseEntity<Boolean> delete(
        @Parameter(description = "任务id") @RequestParam(required = true) Long taskId) {
        var result = apiWsApplicationService.deleteTask(taskId);
        return RestResponseEntity.success(result);
    }

    // =====新建任务流程接口 第一步======
//    @AuthorityAnnotation(menuId = MenuEnumNew.WEB, readWriteStatus = 1, isAdd = 1)
    @Operation(summary = "根据wsdl服务地址获取端口号和方法列表, 供前端下拉框选择")
    @PostMapping(value = "/getWsdlPortOperationMap")
    public RestResponseEntity<GetServiceDTO> getWsdlPortsAndMethods(
        @Valid @RequestBody GetServiceRequest getServiceRequest) {
        var result = apiWsApplicationService.getWsdlPortsAndMethods(getServiceRequest);
        return RestResponseEntity.success(result);
    }

    //    @AuthorityAnnotation(menuId = MenuEnumNew.WEB, readWriteStatus = 1, isAdd = 1)
    @PostMapping("/test")
    @Operation(summary = "接口测试")
    @LogExecution(operation = EngineOperation.START_TASK, business = Business.接口采集)
    public RestResponseEntity test(@Valid @RequestBody TestApiWsRequest testApiwsRequest) {
        var result = apiWsApplicationService.test(testApiwsRequest);
        return RestResponseEntity.success(result);
    }

    //    @AuthorityAnnotation(menuId = MenuEnumNew.WEB, readWriteStatus = 1, isAdd = 1)
    @PostMapping("/uploadJar")
    @Operation(summary = "上传jar包")
//    @Log(
//        business = Business.接口采集,
//        operation = Operation.UPLOAD)
    @LogExecution(operation = EngineOperation.UPLOAD, business = Business.接口采集)
    public RestResponseEntity uploadJar(@RequestPart("file") MultipartFile file) {
        var result = apiWsApplicationService.uploadJar(file);
        return RestResponseEntity.success(result);
    }

    //    @AuthorityAnnotation(menuId = MenuEnumNew.WEB, readWriteStatus = 1, isAdd = 1)
    @PostMapping("/preview")
    @Operation(summary = "预览")
    @LogExecution(operation = EngineOperation.PRE_VIEW, business = Business.接口采集)
    public RestResponseEntity preview(
        @Valid @RequestBody PreviewExpressRequest previewExpressRequest) {
        var result = apiWsApplicationService.preview(previewExpressRequest);
        return RestResponseEntity.success(result);
    }

    // =====新建任务流程接口 第二步选表或建表======
//    @AuthorityAnnotation(menuId = MenuEnumNew.WEB, readWriteStatus = 0, isAdd = 1)
    @GetMapping("/getDatabases")
    @Operation(summary = "获取数据目标")
    public RestResponseEntity<GetDataSourceDTO> getDatabases() {
        Long projectId = ServletUtils.getProjectId();
        var result = apiWsApplicationService.getDatabases(projectId);
        return RestResponseEntity.success(result);
    }

    //    @AuthorityAnnotation(menuId = MenuEnumNew.WEB, readWriteStatus = 0, isAdd = 1)
    @GetMapping("/getTargetTables")
    @Operation(summary = "获取目标表")
    public RestResponseEntity<GetTargetTablesDTO> getTargetTables(
        @Parameter(description = "数据源Id") @RequestParam(required = true) Long dsId) {
        var result = apiWsApplicationService.getTargetTables(dsId);
        return RestResponseEntity.success(result);
    }

    //    @AuthorityAnnotation(menuId = MenuEnumNew.WEB, readWriteStatus = 1, isAdd = 1)
    @PostMapping("/getCreateTableDDL")
    @Operation(summary = "获取一键建表语句")
    public RestResponseEntity<GetCreateTableDDLDTO> getCreateTableDDL(
        @Valid @RequestBody GetCreateTableDDLRequest getCreateTableDDLRequest) {
        var result = apiWsApplicationService.getCreateTableDDL(getCreateTableDDLRequest);
        return RestResponseEntity.success(result);
    }

    //    @AuthorityAnnotation(menuId = MenuEnumNew.WEB, readWriteStatus = 1, isAdd = 1)
    @PostMapping("/saveTargetTable")
//    @Log(
//        business = Business.接口采集,
//        operation = Operation.DATA_SYNC_CREATE_TABLE)
    @Operation(summary = "一键建表")
    @ProjectStatisticExecution(type = ProjectStatisticTypeEnum.TABLE)
    @LogExecution(operation = EngineOperation.DATA_SYNC_CREATE_TABLE, business = Business.接口采集)
//    @ProjectStatisticExecution(description = "已创建数据表", primaryClassification = 5)
    public RestResponseEntity saveTargetTable(
        @Validated @RequestBody SaveTargetTableRequest saveTargetTableRequest) {
        var result = apiWsApplicationService.saveTargetTable(saveTargetTableRequest);
        return RestResponseEntity.success(result);
    }

    // =====新建任务流程接口 第三步配置字段映射======
//    @AuthorityAnnotation(menuId = MenuEnumNew.WEB, readWriteStatus = 0, isAdd = 1)
    @GetMapping("/getTagetTableFields")
    @Operation(summary = "获取关联映射字段")
    public RestResponseEntity<GetFieldsDTO> getTargetTableFields(
        @Parameter(description = "数据源Id") @RequestParam(required = true) Long dsId,
        @Parameter(description = "表名") @RequestParam(required = true) String tableName) {
        var result = apiWsApplicationService.getTargetTableFields(dsId, tableName);
        return RestResponseEntity.success(result);
    }

    //    @AuthorityAnnotation(menuId = MenuEnumNew.WEB, readWriteStatus = 0)
    @Operation(summary = "获取日志信息", description = "获取日志信息")
//    @ApiImplicitParams({
//        @ApiImplicitParam(
//            paramType = "header",
//            dataType = "String",
//            name = Constants.HEADER_PROJECT_ID,
//            value = "项目id标识",
//            required = true),
//    })
    @GetMapping("/log")
    public RestResponseEntity<ApiHttpLogDTO> getOfflineSyncLog(
        @Parameter(description = "离线同步任务LogId") @RequestParam Long logId,
        @Parameter(description = "偏移量", required = true) @RequestParam("offset") Integer offset) {
        var result = apiWsApplicationService.getOfflineSyncLog(logId, offset);
        return RestResponseEntity.success(result);
    }

    /**
     * 终止运行任务
     *
     * @param logId
     * @return
     */
//    @AuthorityAnnotation(menuId = MenuEnumNew.WEB, readWriteStatus = 1)
    @Operation(summary = "终止运行任务", description = "终止运行任务")
//    @ApiImplicitParams({
//        @ApiImplicitParam(
//            paramType = "header",
//            dataType = "String",
//            name = Constants.HEADER_PROJECT_ID,
//            value = "项目id标识",
//            required = true),
//    })
    @PostMapping("/stop")
//    @Log(
//        business = Business.接口采集,
//        operation = Operation.STOP_TASK)
    @LogExecution(operation = EngineOperation.STOP_TASK, business = Business.接口采集)
    public RestResponseEntity<Boolean> stopTask(
        @Parameter(description = "离线同步任务id", required = true) @RequestParam("logId") Long logId) {
        var result = apiWsApplicationService.stopTask(logId);
        return RestResponseEntity.success(result);
    }
}
